<?php

namespace cf;

class Mail                                                                  
{                                                                           
   function __construct($subject, $body)
   {                                                                        
	  $this->headers['MIME-Version'] = '1.0';
	  $this->setCharset('UTF-8');
      $this->setTypeHTML();                                                 
	  $this->setSubject($subject);
	  
	  $this->body = $body;
   }                                                                        
                                                                            
   public function setSubject($subject)                                     
   {                                                                        
      $this->subject = $subject;
   }                                                                        
                                                                            
   public function setTypePlain()
   {                                                                        
      $this->headers['Content-Type'] = 'text/plain';
   }                                                                        

   public function setTypeHTML()
   {
      $this->headers['Content-Type'] = 'text/html';
   }                                                                        
                                                                            
   public function setCharset($charset)                                     
   {
	  $this->setHeader('charset', $charset);
   }                                                                        
   
   public function setFrom($from)
   {             
	  $this->setHeader('From', $from);
   }   
                                                                            
   public function setHeader($name,$val)
   {
	  $this->headers[trim($name)] = trim($val);
   }
                                                                       
                                                                            
   public static function send($to, Mail $message)
   {                                                                        
      assert(is_string($to)); 
	  
      if (!mail(                                                            
            $to,                                                            
            $message->encodeSubject($message->subject),                           
            $message->body,                                                     
            $message->headersToString()))                                      
      {                                                                     
         //throw new Exception("Can't send email [$message->subject] to [$to]");
      }                                                                     
   }
   
   static public function validate($email)
   {
   /**
			www.linuxjournal.com/article/9585
   
		Validate an email address.
		Provide email address (raw input)
		Returns true if the email address has the email 
		address format and the domain exists.
	*/
	   $isValid = true;
	   $atIndex = strrpos($email, "@");
	   if (is_bool($atIndex) && !$atIndex)
	   {
		  $isValid = false;
	   }
	   else
	   {
		  $domain = substr($email, $atIndex+1);
		  $local = substr($email, 0, $atIndex);
		  $localLen = strlen($local);
		  $domainLen = strlen($domain);
		  if ($localLen < 1 || $localLen > 64)
		  {
			 // local part length exceeded
			 $isValid = false;
		  }
		  else if ($domainLen < 1 || $domainLen > 255)
		  {
			 // domain part length exceeded
			 $isValid = false;
		  }
		  else if ($local[0] == '.' || $local[$localLen-1] == '.')
		  {
			 // local part starts or ends with '.'
			 $isValid = false;
		  }
		  else if (preg_match('/\\.\\./', $local))
		  {
			 // local part has two consecutive dots
			 $isValid = false;
		  }
		  else if (!preg_match('/^[A-Za-z0-9\\-\\.]+$/', $domain))
		  {
			 // character not valid in domain part
			 $isValid = false;
		  }
		  else if (preg_match('/\\.\\./', $domain))
		  {
			 // domain part has two consecutive dots
			 $isValid = false;
		  }
		  else if (!preg_match('/^(\\\\.|[A-Za-z0-9!#%&`_=\\/$\'*+?^{}|~.-])+$/', str_replace("\\\\","",$local)))
		  {
			 // character not valid in local part unless 
			 // local part is quoted
			 if (!preg_match('/^"(\\\\"|[^"])+"$/',
				 str_replace("\\\\","",$local)))
			 {
				$isValid = false;
			 }
		  }
		  if ($isValid && !(checkdnsrr($domain,"MX") || checkdnsrr($domain,"A")))
		  {
			 // domain not found in DNS
			 $isValid = false;
		  }
	   }
	   return $isValid;
   }
   

   
   private function encodeSubject($subject)
   {                                                                                   
      if (!array_key_exists('charset', $this->headers))                                
      {                                                                                
         return $subject;                                                              
      }                                                                                
      return '=?' . $this->headers['charset'] . '?B?' . base64_encode($subject) . '?=';
	  
		/*
			subject - поле заголовка!
			в заголовках ни при каких обстоятельствах не должны содержаться символы, не присутствующие в ASCII таблице 
			Общий формат кодирования "запрещенных" символов:
				=?кодировка?способ кодирования?закодированный текст?=
			кодировка = "windows-1251", "koi8-r", "utf-8" ...
			Способ кодирования: Q-quoted printable encoding, B-Base64 encoding
		*/
   }                                                                                   
                                                                                       
   private function headersToString()
   {                                                                                   
      $s = '';                                                                         
      foreach ($this->headers as $nm => $val)                                          
      {                                                                                
         if (!empty($s) && $nm != 'charset')
         {                                                                             
            $s .= "\r\n";                
         }                                                                             
         if ($nm == 'Content-Type')                                                    
         {                                                                             
            $val .= '; charset=' . $this->headers['charset'];                          
         }                                                                             
         if ($nm != 'charset')                                                         
         {  
            $s .= "$nm: $val";                                                         
         }

			
      }                                                                                
      return $s;                                                                       
   }                                                                                   

   private $subject = '';     
   private $headers = array();
   private $body = '';
};

?>